package com.system.service.imp;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.common.Enums.ResponseEnum;
import com.common.Enums.UserEnum;
import com.common.exception.CourseException;
import com.common.util.CopyUtil;
import com.common.util.UuidUtil;
import com.core.system.domain.User;
import com.core.system.mapper.UserMapper;
import com.core.system.service.imp.UserServiceImp;
import com.system.Excel.UserExcel;
import com.system.dto.LoginUserDto;
import com.system.dto.ResourceDto;
import com.system.dto.UserDto;
import com.system.mapper.UserExMapper;
import com.system.service.UserExService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.DigestUtils;
import org.springframework.util.StringUtils;

import java.util.*;


@Service
@Primary
@Slf4j
public class UserExServiceImp extends UserServiceImp implements UserExService {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private UserExMapper userExMapper;


    /**
     * 保存，id有值时更新，无值时新增
     */
    @Override
    public ResponseEntity save(com.core.system.dto.UserDto userDto) {
        if(!StringUtils.isEmpty(userDto.getPassword())) {
            userDto.setPassword(DigestUtils.md5DigestAsHex(userDto.getPassword().getBytes()));
        }
        User user = CopyUtil.copy(userDto, User.class);
        if (StringUtils.isEmpty(userDto.getId())) {
            return this.insert(user);
        } else {
            return this.update(user);
        }

    }

    /**
     * 更新
     */
    private ResponseEntity update(User user) {
        int i = userMapper.updateById(user);
        if (i <= 0) {
            throw new CourseException(ResponseEnum.UPDATE_ERROR);
        }
        return ResponseEntity.ok().build();
    }

    /**
     * 新增
     */
    private ResponseEntity insert(User user) {
        user.setId(UuidUtil.getShortUuid());
        User user1 = selectByLoginName(user.getLoginName());
        if (user1 != null) {
            throw new CourseException(UserEnum.USER_NAME_EXITE);
        }
        int i = userMapper.insert(user);
        if (i <= 0) {
            throw new CourseException(ResponseEnum.ADD_ERROR);
        }
        return ResponseEntity.ok().build();
    }


    /**
     * 根据登录名查询用户信息
     *
     * @param loginName
     * @return
     */
    public User selectByLoginName(String loginName) {
        User user = userMapper.selectOne(new LambdaQueryWrapper<User>()
                .eq(User::getLoginName, loginName));
        return user;
    }

    @Override
    public ResponseEntity savePassword(UserDto userDto) {
        User copy = CopyUtil.copy(userDto, User.class);
        int i = userMapper.updateById(copy);
        if (i <= 0) {
            throw new CourseException(ResponseEnum.UPDATE_ERROR);
        }
        return ResponseEntity.ok().build();
    }

    @Override
    public List<ResourceDto> findUserResources(String userId) {
        return userExMapper.findUserResources(userId);
    }
    /**
     * 登录
     *
     * @param userDto
     */
    public LoginUserDto login(UserDto userDto) {
        User user = selectByLoginName(userDto.getLoginName());
        if (user == null) {
            log.info("用户名不存在, {}", userDto.getLoginName());
            throw new CourseException(UserEnum.USER_LOGIN_ERROR);
        } else {
            log.info(user.toString());
            if (user.getPassword().equals(userDto.getPassword())) {
                if (user.getStatus() == 0) {
                    throw new CourseException(UserEnum.USER_COUNTER_FREEZES);
                }
                // 登录成功
                LoginUserDto loginUserDto = CopyUtil.copy(user, LoginUserDto.class);
                // 为登录用户读取权限
                setAuth(loginUserDto);
                return loginUserDto;
            } else {
                log.info("密码不对, 输入密码：{}, 数据库密码：{}", userDto.getPassword(), user.getPassword());
                throw new CourseException(UserEnum.USER_LOGIN_ERROR);
            }
        }
    }

    /**
     * 获取角色用户信息
     *
     * @param roleId 角色id
     * @return
     */
    @Override
    public ResponseEntity getUserRoleData(String roleId) {
        Map data = new HashMap<>();
        data.put("NoRoleUserList", userExMapper.getNoRoleUser());
        data.put("RoleUserList", userExMapper.getRoleUser(roleId));
        return ResponseEntity.ok(data);
    }

    /**
     * 为登录用户读取权限
     */
    private void setAuth(LoginUserDto loginUserDto) {
        List<ResourceDto> resourceDtoList = userExMapper.findUserResources(loginUserDto.getId());
        HashSet<String> requestSet = getResquestStrings(resourceDtoList);
        loginUserDto.setResources(getTreeResource(resourceDtoList));
        // 整理所有有权限的请求，用于接口拦截
        log.info("有权限的请求：{}", requestSet);
        loginUserDto.setRequests(requestSet);
    }

    /**
     * 格式化成资源树
     *
     * @param resourceDtoList
     */
    private List<ResourceDto> getTreeResource(List<ResourceDto> resourceDtoList) {
        for (int i = resourceDtoList.size() - 1; i >= 0; i--) {
            // 当前要移动的记录
            ResourceDto child = resourceDtoList.get(i);
            // 如果当前节点没有父节点，则不用往下了
            if (StringUtils.isEmpty(child.getParent())) {
                continue;
            }
            // 查找父节点
            for (int j = resourceDtoList.size() - 1; j >= 0; j--) {
                ResourceDto parent = resourceDtoList.get(j);
                if (child.getParent().equals(parent.getId())) {
                    if (CollectionUtils.isEmpty(parent.getChildren())) {
                        parent.setChildren(new ArrayList<>());
                    }
                    // 添加到最前面，否则会变成倒序，因为循环是从后往前循环的
                    if (!parent.getChildren().contains(child)) {
                        parent.getChildren().add(0, child);
                    }
                    // 子节点找到父节点后，删除列表中的子节点
//                    resourceDtoList.remove(child);

                }
            }

        }
        List<ResourceDto> resourceDtoList1 = new ArrayList<>();
        for (int i = 0; i < resourceDtoList.size(); i++) {
            if (StringUtils.isEmpty(resourceDtoList.get(i).getParent())) {
                resourceDtoList1.add(resourceDtoList.get(i));
            }
        }
        resourceDtoList.clear();
        return resourceDtoList1;
    }

    /**
     * 获取有权限的请求路径
     *
     * @param resourceDtoList
     * @return
     */
    private HashSet<String> getResquestStrings(List<ResourceDto> resourceDtoList) {
        HashSet<String> requestSet = new HashSet<>();
        if (!CollectionUtils.isEmpty(resourceDtoList)) {
            for (int i = 0, l = resourceDtoList.size(); i < l; i++) {
                ResourceDto resourceDto = resourceDtoList.get(i);
                String arrayString = resourceDto.getRequest();
                List<String> requestList = JSON.parseArray(arrayString, String.class);
                if (!CollectionUtils.isEmpty(requestList)) {
                    requestSet.addAll(requestList);
                }
            }
        }
        return requestSet;
    }

    @Override
    public List<UserExcel> ExportList() {
        List<User> users = baseMapper.selectList(new LambdaQueryWrapper<User>().orderBy(true, false, User::getCreateTime));
        return CopyUtil.copyList(users, UserExcel.class);
    }

    @Override
    public ResponseEntity insertList(List<UserExcel> userList) {
        return ResponseEntity.ok(userExMapper.insertList(userList));
    }

}
